<?php

namespace Kcdns\Service\Oauth\SDK;

use Kcdns\Service\Oauth\OauthSDK;

class WeixinSDK extends OauthSDK
{

    /**
     * 获取requestCode的api接口
     * @var string
     */
    protected $GetRequestCodeURL = 'connect/oauth2/authorize';

    /**
     * 获取access_token的api接口
     * @var string
     */
    protected $GetAccessTokenURL = 'sns/oauth2/access_token';

    /**
     * API根路径
     * @var string
     */
    protected $ApiBase = 'https://api.weixin.qq.com/';

    protected $scope = "snsapi_userinfo";//"snsapi_userinfo"   静默授权： snsapi_base

    /**
     * 请求code
     */
    public function getRequestCodeURL($callback)
    {

        if (!empty($callback))
            $this->Callback = $callback;
        else
            throw new \Exception('请配置回调页面地址');

        //Oauth 标准参数
        $params["appid"] = $this->AppKey;
        $params["redirect_uri"] = $this->Callback;
        $params["response_type"] = $this->ResponseType;
        $params["scope"] = $this->scope;
        $params["state"] = "STATE" . "#wechat_redirect";

        //获取额外参数
        if ($this->Authorize) {
            parse_str($this->Authorize, $_param);
            if (is_array($_param)) {
                $params = array_merge($params, $_param);
            } else {
                throw new \Exception('AUTHORIZE配置不正确！');
            }
        }
        return $this->GetRequestCodeURL . '?' . http_build_query($params);
    }


    /**
     * 组装接口调用参数 并调用接口
     * @param  string $api 微信API
     * @param  string $param 调用API的额外参数
     * @param  string $method HTTP请求方法 默认为GET
     * @return json
     */
    public function call($api, $param = '', $method = 'GET', $multi = false)
    {
        /* 腾讯微信调用公共参数 */
        $params = array(
            'access_token' => $this->Token['access_token'],
            'openid' => $this->openid(),
            'lang' => 'zh_CN'
        );

        $vars = $this->param($params, $param);
        $data = $this->http($this->url($api), $vars, $method, array(), $multi);
        return json_decode($data, true);
    }

    /**
     * 解析access_token方法请求后的返回值
     * @param string $result 获取access_token的方法的返回值
     */
    protected function parseToken($result, $extend)
    {
        $data = json_decode($result, true);

        if (IS_ENTERPRISE_WX) {
            if (!$data['access_token'] || !$this->code) throw new \Exception("获取腾讯微信 ACCESS_TOKEN 出错：{$result}");

            $get = [
                'access_token' => $data['access_token'],
                'code' => $this->code
            ];
            $url = 'https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo';
            $str = $this->http($url, $get, 'GET');
            $arr = json_decode($str, true);
            if (!$arr || !$arr['UserId']) throw new \Exception("获取成员信息 出错：{$str}");

            $data['openid'] = $this->AppKey . '_' . $arr['UserId'];
        }

        if ($data['access_token'] && $data['expires_in'] && $data['openid'])
            return $data;
        else
            throw new \Exception("获取腾讯微信 ACCESS_TOKEN 出错：{$result}");
    }

    /**
     * 获取当前授权应用的openid
     * @return string
     */
    public function openid()
    {
        $data = $this->Token;
        if (isset($data['openid']))
            return $data['openid'];
        else
            throw new \Exception('没有获取到openid！');
    }

    /**
     * 获取access_token
     * @param string $code 上一步请求到的code
     */
    public function getAccessToken($code, $extend = null)
    {

        $params = array(
            'appid' => $this->AppKey,
            'secret' => $this->AppSecret,
            'grant_type' => $this->GrantType,
            'code' => $code,
            'redirect_uri' => $this->Callback,
        );

        if (IS_ENTERPRISE_WX) {
            $params = array(
                'corpid' => $this->AppKey,
                'corpsecret' => $this->AppSecret,
                'grant_type' => $this->GrantType,
                'code' => $code,
                'redirect_uri' => $this->Callback,
            );
            $this->GetAccessTokenURL = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken';
            $this->code = $code;
        }

        $data = $this->http($this->GetAccessTokenURL, $params, 'GET');
        $this->Token = $this->parseToken($data, $extend, $code);
        return $this->Token;
    }

    /**
     * 获取用户信息--静默授权
     */
    public function getUserInfo()
    {
        if (IS_ENTERPRISE_WX) {
            if (!$this->Token['openid']) throw new \Exception("获取微信用户信息失败IS_ENTERPRISE_WX");
            $userInfo['name'] = str_replace($this->AppKey . '_', '', $this->Token['openid']);
            $userInfo['nickname'] = $userInfo['name'];
            $userInfo['head'] = '';
            return $userInfo;
        }

        if ($this->scope == 'snsapi_base') {
            return [];
        }

        $data = $this->call('sns/userinfo');
        if (isset($data['openid'])) {
            $userInfo['name'] = $data['openid'];
            $userInfo['nickname'] = $data['nickname'];
            $userInfo['head'] = $data['headimgurl'];
            return $userInfo;
        } else {
            $data = var_export($data, true);
            throw new \Exception("获取微信用户信息失败：{$data}");
        }
    }

    /**
     * 获取用户信息--静默授权
     */
    public function getUserInfoFull()
    {

        if (IS_ENTERPRISE_WX) {
            if (!$this->Token['openid']) throw new \Exception("获取微信用户信息失败IS_ENTERPRISE_WX");
            $userInfo['name'] = str_replace($this->AppKey . '_', '', $this->Token['openid']);
            $userInfo['nickname'] = $userInfo['name'];
            $userInfo['head'] = '';
            return $userInfo;
        }

        $this->scope = 'snsapi_userinfo';

        $data = $this->call('sns/userinfo');
        if (isset($data['openid'])) {
            $userInfo['name'] = $data['openid'];
            $userInfo['nickname'] = $data['nickname'];
            $userInfo['head'] = $data['headimgurl'];
            return $userInfo;
        } else {
            $data = var_export($data, true);
            throw new \Exception("获取微信用户信息失败：{$data}");
        }
    }
}